package com.dingreading.cloud.admin.controller;

import com.alibaba.fastjson.JSONArray;
import com.dingreading.cloud.admin.entity.CmactivationCodeType;
import com.dingreading.cloud.admin.entity.SubjectLesson;
import com.dingreading.cloud.admin.entity.Subjects;
import com.dingreading.cloud.admin.service.CmactivationCodeTypeService;
import com.dingreading.cloud.admin.service.SubjectLessonService;
import com.dingreading.cloud.admin.service.SubjectsService;
import com.dingreading.cloud.admin.util.TreeJsonUtil;
import com.dingreading.cloud.admin.util.bean.SubjectUtil;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.NepUtil;
import com.dingreading.cloud.common.util.RedisParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/system/subjects/v2")
@Api(tags = "总部-学科管理")
public class SubjectsControllerV2 {

    @Resource
    private SubjectsService subjectsService;
    @Resource
    private SubjectLessonService subjectLessonService;
    @Resource
    private RedisService redisService;
    @Resource
    private CmactivationCodeTypeService cmactivationCodeTypeService;


    @ApiOperation(value = "学科tree")
    @PostMapping(value = "/treeList")
    public R<Object> treeList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "主学科id") @RequestParam(value = "id", required = false) Long id
    ) {
        JSONArray treeJson = new JSONArray();
        List<Subjects> subjectsList;
        if (id != null && id > 0) {
            subjectsList = subjectsService.getBySubjectMainId(id);
        } else {
            subjectsList = subjectsService.getBySubjectMainId(null);
        }
        if (CollectionUtils.isNotEmpty(subjectsList)) {
            treeJson = TreeJsonUtil.createTreeJson(subjectsList);
        }
        return R.ok(treeJson);
    }


    @ApiOperation(value = "新增/修改主学科")
    @PostMapping(value = "/newMainSubject")
    public R<Object> newMainSubject(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "学科id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "学科名称") @RequestParam(value = "subjectName") String subjectName,
            @ApiParam(value = "前端展示序号") @RequestParam(value = "showOrder", required = false) Integer showOrder,
            @ApiParam(value = "门店合作类型") @RequestParam(value = "cooperationType", required = false) String cooperationType
    ) {
        if (id == null || id <= 0) {
            // 新增
            Long aLong = subjectsService.duplicationSubjectMainName(null, subjectName);
            if (aLong > 0) return R.fail("学科名重复了");
            // 获取最大的主学科展示序号
            int maxShowOrder = subjectsService.getMaxShowOrder();

            Subjects subjects = SubjectUtil.newMainSubject(subjectName, maxShowOrder + 1, cooperationType);

            subjectsService.saveOrUpdate(subjects);
            subjectsService.updateSubjectMainIdAndNodes(subjects.getId());
        } else {
            // 修改
            Subjects subjects = subjectsService.getById(id);
            if (subjects == null) return R.fail("学科获取失败");

            Long aLong = subjectsService.duplicationSubjectMainName(id, subjectName);
            if (aLong > 0) return R.fail("学科名重复了");

            if (subjectName != null)
                subjects.setSubjectName(subjectName);
            if (showOrder != null)
                subjects.setShowOrder(showOrder);
            subjects.setCooperationType(cooperationType);
            subjectsService.saveOrUpdate(subjects);
        }

        // 清空redis缓存
        clearRedis();

        return R.ok();
    }

    @ApiOperation(value = "新增/修改子学科")
    @PostMapping(value = "/newChildSubject")
    public R<Object> newChildSubject(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "关联学科id") @RequestParam(value = "parentId", required = false) Long parentId,
            @ApiParam(value = "学科id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "子学科名称") @RequestParam(value = "subjectName") String subjectName,
            @ApiParam(value = "课程简介") @RequestParam(value = "subjectDescribe", required = false) String subjectDescribe,
            @ApiParam(value = "层级名") @RequestParam(value = "levelName") String levelName,
            @ApiParam(value = "是否最后一级 0，否 1，是") @RequestParam(value = "levelEnd", required = false) int levelEnd,
            @ApiParam(value = "课次数量") @RequestParam(value = "lessonNum", required = false) Integer lessonNum,
            @ApiParam(value = "是否免费 0.不 1.免费") @RequestParam(value = "freeStatus", required = false) Integer freeStatus
    ) {
        Subjects parentSubjects = subjectsService.getById(parentId);
        if (parentSubjects == null) return R.fail("上级学科获取失败");
        if (parentSubjects.getLevelEnd().equals(1)) return R.fail("上级学科是最后一级，不能新增子学科");

        Subjects mainSubjects = subjectsService.getById(parentSubjects.getSubjectMainId());
        if (mainSubjects == null) return R.fail("主学科获取失败");

        if (id == null || id <= 0) {
            // 新增
            // 获取层级内的最大序号
            Integer maxSubjectOrder = subjectsService.getMaxSubjectOrderByPatentId(parentId) + 1;
            // 获取层级序号
            int levelIndex = NepUtil.nullToZero(parentSubjects.getLevelIndex()) + 1;
            if (levelEnd != 1) {
                levelEnd = 0;
                lessonNum = 0;
            }
            Subjects childSubject = SubjectUtil.newChildSubject(
                    id, mainSubjects.getId(), parentId, subjectName, subjectDescribe,
                    maxSubjectOrder, levelName, levelEnd, lessonNum, levelIndex, 1
            );
            subjectsService.saveOrUpdate(childSubject);

            if (childSubject.getId() == null || childSubject.getId() <= 0)
                return R.fail("添加失败");
            String nodes = parentSubjects.getNodes() + childSubject.getId() + ",";
            subjectsService.updateNodes(childSubject.getId(), nodes);

            // 最后一级，批量生成课次
            if (levelEnd == 1 && lessonNum > 0) {
                List<SubjectLesson> newLessonList = new ArrayList<>();
                for (int i = 1; i <= lessonNum; i++) {
                    SubjectLesson newLesson = SubjectUtil.newLesson(
                            mainSubjects.getId(), mainSubjects.getSubjectName(), childSubject.getId(), i, nodes
                    );
                    newLessonList.add(newLesson);
                }
                if (CollectionUtils.isNotEmpty(newLessonList))
                    subjectLessonService.saveOrUpdateBatch(newLessonList);
            }
        } else {
            // 修改
            Subjects subjects = subjectsService.getById(id);
            if (subjects == null) return R.fail("学科获取失败");

            Subjects childSubject = SubjectUtil.editChildSubject(
                    subjects, subjectName, subjectDescribe, levelName
            );
            subjectsService.saveOrUpdate(childSubject);
        }

        // 清空redis缓存
        clearRedis();

        return R.ok();
    }


    @ApiOperation(value = "根据ID获取学科信息")
    @PostMapping(value = "/getById", produces = "application/json; charset=UTF-8")
    public R<Object> getById(
            HttpServletRequest request,
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "学科id") @RequestParam(value = "id") Long id
    ) {
        return subjectsService.getSubjectDto(request, headStaffUid, headStaffName, id);
    }


    @ApiOperation(value = "更新学科启用状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "学科id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "状态 0.禁用 1.启用") @RequestParam(value = "enabled") Integer enabled
    ) {
        Subjects data = subjectsService.getById(id);
        if (data == null) return R.fail("获取失败");

        if (data.getParentId().equals(0L)) {
            // 如果是主分类，适用其下所有分类
            subjectsService.updateEnabledBySubjectMainId(data.getId(), enabled);
        } else {
            // 如果是子分类，适用其下所有分类
            subjectsService.updateEnabledByParentId(id, enabled);
        }

        // 清空redis缓存
        clearRedis();

        return R.ok();
    }


    @ApiOperation(value = "获取主学科列表")
    @PostMapping(value = "/getMainSubjects", produces = "application/json; charset=UTF-8")
    public R<Object> getMainSubjects(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        List<Subjects> mainSubjects = subjectsService.mainListByEnabled(null);

        return R.ok(mainSubjects);
    }


    @ApiOperation(value = "上移/下移")
    @PostMapping(value = "/upOrDown", produces = "application/json; charset=UTF-8")
    public R<Object> upOrDown(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "学科id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "类型 1.上移 2.下移") @RequestParam(value = "type") Integer type
    ) {
        Subjects data = subjectsService.getById(id);
        if (data == null) return R.fail("获取失败");
        if (type.equals(1)) {
            // 上移
            Subjects preDate = subjectsService.getLtSubjectOrder(data.getParentId(), data.getSubjectOrder());
            if (preDate == null) return R.fail("已在最前");
            // 和前一条记录的序号互换
            Integer prevOrderNum = preDate.getSubjectOrder();
            Integer curOrderNum = data.getSubjectOrder();
            // 序号互换
            subjectsService.updateSubjectOrder(preDate.getId(), curOrderNum);
            subjectsService.updateSubjectOrder(data.getId(), prevOrderNum);
        } else if (type.equals(2)) {
            // 下移
            Subjects backData = subjectsService.getGtSubjectOrder(data.getParentId(), data.getSubjectOrder());
            if (backData == null) return R.fail("已在最后");
            // 和后一条记录的序号互换
            Integer backOrderNum = backData.getSubjectOrder();
            Integer curOrderNum = data.getSubjectOrder();
            // 序号互换
            subjectsService.updateSubjectOrder(backData.getId(), curOrderNum);
            subjectsService.updateSubjectOrder(data.getId(), backOrderNum);
        } else {
            return R.fail("类型错误");
        }
        // 清空redis缓存
        clearRedis();
        return R.ok();
    }


    @ApiOperation(value = "获取用于轻量产品加盟的学科集合")
    @PostMapping(value = "/getOperationSubjectList", produces = "application/json; charset=UTF-8")
    public R<Object> getOperationSubjectList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        List<Subjects> list = subjectsService.mainListByEnabled(1);

        return R.ok(list);
    }

    @ApiOperation(value = "上传资料信息")
    @PostMapping(value = "/uploadInfo")
    public R<Object> uploadInfo(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "子分类id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "书本isbn") @RequestParam(value = "bookIsbn", required = false) String bookIsbn,
            @ApiParam(value = "书本出版社") @RequestParam(value = "bookPress", required = false) String bookPress,
            @ApiParam(value = "书本封面图") @RequestParam(value = "bookImg", required = false) String bookImg
    ) {
        return subjectsService.uploadInfo(headStaffUid, headStaffName, id, bookIsbn, bookPress, bookImg);
    }

    @ApiOperation(value = "设置子学科激活信息")
    @PostMapping(value = "/setActivation")
    public R<Object> setActivation(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "关联学科id") @RequestParam(value = "parentId") Long parentId,
            @ApiParam(value = "学科id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "激活码金额") @RequestParam(value = "activateAmount") Double activateAmount,
            @ApiParam(value = "激活码类型uid") @RequestParam(value = "activationTypeUid") String activationTypeUid
    ) {
        if (activateAmount == null || activateAmount <= 0)
            return R.fail("请设置激活金额");
        if (StringUtils.isBlank(activationTypeUid))
            return R.fail("请选择激活码类型");
        Subjects parentSubjects = subjectsService.getById(parentId);
        if (parentSubjects == null) return R.fail("上级学科获取失败");
        if (parentSubjects.getLevelEnd().equals(1)) return R.fail("上级学科是最后一级，不能设置激活信息");

        Subjects mainSubjects = subjectsService.getById(parentSubjects.getSubjectMainId());
        if (mainSubjects == null) return R.fail("主学科获取失败");

        String activationTypeName = null;
        if (StringUtils.isNotBlank(activationTypeUid)) {
            CmactivationCodeType cmactivationCodeType = cmactivationCodeTypeService.getByUid(activationTypeUid);
            if (cmactivationCodeType == null)
                return R.fail("激活码类型获取失败");
            activationTypeName = cmactivationCodeType.getActivationName();
        }

        // 修改
        Subjects subjects = subjectsService.getById(id);
        if (subjects == null) return R.fail("学科获取失败");
        if (!subjects.getLevelEnd().equals(1))
            return R.fail("不是最后一级，不能设置激活信息");
        subjects.setActivateAmount(NepUtil.nullToZero(activateAmount));
        subjects.setActivationTypeUid(NepUtil.nullToZero(activationTypeUid));
        subjects.setActivationTypeName(NepUtil.nullToZero(activationTypeName));
        subjectsService.saveOrUpdate(subjects);
        return R.ok();
    }


    /**
     * 清空redis缓存
     */
    private void clearRedis() {
        redisService.setNullLike(RedisParam.MAIN_SUBJECT);
        redisService.setNullLike(RedisParam.CHILD_SUBJECT);
        redisService.setNullLike(RedisParam.DXH_SUBJECT);
        redisService.setNullLike(RedisParam.HBJD_SUBJECT);
        redisService.setNullLike(RedisParam.HSYD_SUBJECT);
    }

}